import { ref, computed, reactive } from "vue";
import { useRoute } from "vue-router";
import dayjs from "dayjs";
import request from "@/utils/request";
import { Message } from "@garco-design/web-vue";
import { getNodeAndEdgeStatus, buildApiData } from "./topoService";
import { some, cloneDeep, forEach } from "lodash";
import { traceBackGraph } from "@/api/topo";
export default function useOperation({
  topoRef,
  topoData,
  mode,
  topoDataUserPos,
  attachDataType,
  groupValue,
  getTopoDataByIsMerge,
  getSystemInfoData,
  timeInfo,
}) {
  // const attachDataType = ref(0); //   // 展示同环比数据 0-环比 1-同比
  const tipVisible = ref(false)
  const attachDataTypeText = computed(() => {
    return attachDataType.value ? "切换为环比数据" : "切换为同比数据";
  });
  const isFullScreen = ref(false);
  const { query } = useRoute();
  const syncEntranceConfig = reactive({
    loading: false,
  });
  const traceBackConfig = reactive({
    isTraceBack: false,
    loading: false,
  });
  const dataFilter = reactive({
    count: 20,
    field: 'responseTime'
  })
  const nodeModes = [{
    label: '方形节点',
    value: 'rect'
  }, {
    label: '圆形节点',
    value: 'circle'
  }]
  const nodeMode = ref('rect')
  const filters = {
    count: [{
      label: 'Top20',
      value: 20
    },{
      label: 'Top50',
      value: 50
    },{
      label: 'Top100',
      value: 100
    },{
      label: 'Top200',
      value: 200
    },{
      label: '全部',
      value: 99999
    }],
    fields: [{
      value: 'responseTime',
      label: '响应时间'
    }, {
      label: '请求量',
      value: 'requestTotal'
    }, {
      label: '错误率',
      value: 'errorRate'
    }]
  }
  // 当前拓扑图统计的时间范围
  const queryTime = reactive({from:"", to:''})
  // 调用拓扑请求时间（回溯需要setState queryTime，保留一份请求数据，关闭回溯后setState为topoQueryTime）
  const topoQueryTime = reactive({ from: "", to: "" });
  const trackBackData = ref([]);

  function updateAutoSync(checked) {
    syncEntranceConfig.loading = true;
    const params = {
      status: checked ? 1 : 0,
      systemId: query.systemId,
    };
    request
      .get("/system/systemEntranceAutoSync/enable", { params })
      .then((res) => {
        if (res.data) {
          Message.success("更新成功");
          getSystemInfoData();
        } else {
          Message.error("更新失败");
        }
      })
      .finally(() => {
        syncEntranceConfig.loading = false;
      });
  }
  // 改变同环比的显示
  function changeAttachDataType() {
    if (topoRef?.value?.graph) {
      const graph = topoRef.value.graph;

      graph.setAutoPaint(false);
      const nodes = graph.getNodes();
      const edges = graph.getEdges();
      const combos = graph.getCombos()
      nodes.forEach((node) => {
        const nodeModel = node.getModel();
        nodeModel.attachDataType = attachDataType ? 0 : 1;
        graph.updateItem(node, nodeModel);
      });
      edges.forEach((edge) => {
        const edgeModel = edge.getModel();
        edgeModel.attachDataType = attachDataType ? 0 : 1;
        const edgeStatus = getNodeAndEdgeStatus(edgeModel);
        edgeModel.style.stroke = edgeStatus ? "#F7313B" : "#AAAAAA";
        edgeModel.style.endArrow.fill = edgeStatus ? "#F7313B" : "#AAAAAA";
        graph.updateItem(edge, edgeModel);
      });
      // graph.read({edges,nodes, combos})
      console.log(graph, 'graph');

      graph.paint();
      // graph.render()
      console.log(graph.getNodes(), 'nodes', graph.getEdges());

      graph.setAutoPaint(true);
    }
    attachDataType.value = attachDataType.value ? 0 : 1;
  }
  // 点击归并按钮 归并拓扑数据直接使用topoData数据
  function onMerge() {
    if (topoData.value.nodes.length === 0) {
      Message.info("暂无拓扑数据");
      return;
    }
    mode.value = "merge";
    // this.setState({ editMode: 'merge' });
  }

  //点击保存拓扑修改
  function onSaveTopoChange() {
    const loadingMsg =  Message.loading("正在保存中");
    // console.log('要保存的数据', nodesOfModified);
    // console.log('原始数据', this.topoRef.current.graph.cfg);
    // const nodeMap = new Map()
    // const graphMap = new Map()
    try {
      const { nodes: nodesOfModified, combos: combosOfModified = [] } =
        topoRef.value.graph.cfg.data;
      console.log(topoRef.value.graph.cfg.data, "graph");
      // console.log(nodesOfModified, );

      const { systemId } = query;
      const nodesOfModifiedNormalization =
        groupValue.value == "none"
          ? nodesOfModified.map((item) => {
              const { workloadKey, x, y } = item;
              return { nodeKey: workloadKey, xAxis: x, yAxis: y };
            })
          : nodesOfModified
              .map((item) => {
                const { workloadKey, x, y } = item;
                // console.log(workloadKey, x, y);
                return { nodeKey: workloadKey, xAxis: x, yAxis: y };
              })
              .concat(
                combosOfModified.map((item) => {
                  const { id, x, y } = item;
                  return { nodeKey: id, xAxis: x, yAxis: y };
                })
              );
              console.log(groupValue, 'groupValue');

      const data = [
        {
          systemId,
          groupType:
            groupValue.value == "none"
              ? 0
              : groupValue.value == "namespace"
              ? 1
              : groupValue.value == "merge" && 2,
          nodePos: nodesOfModifiedNormalization,
        },
      ];
      const params = {
        systemId,
      };
      // console.log('params of last submit', data, params);
      // request.post('/system-topology/savePosition', data, {params})
      request
        .post("/system-topology/savePosition", data, { params })
        .then((res) => {
          loadingMsg.close()
          res.data ? Message.success("保存成功") : Message.error("保存失败");
          const posParams = {
            systemId,
          };
          request
            .get("/system-topology/getNodePositions", { params: posParams })
            .then((res) => {
              if (res.data.length > 0) {
                const nodeListHasPosByUser = res.data;
                topoDataUserPos.value = nodeListHasPosByUser;
                // console.log('存入公共池子', this.topoDataUserPos);
              }
            });
        });
    } catch (error) {
      console.log(error, "error");
    }
  }
  function onTriggerTrackBack() {
    const { isTraceBack } = traceBackConfig;
    if (isTraceBack) {
      // 关闭回溯
      trackBackData.value = []
      queryTime.value = {...topoQueryTime}
      if (!topoRef.value.graph) {
        return;
      }
      const graph = topoRef.value.graph;
      const data = cloneDeep(topoData.value);
      graph.read(data);
    } else {
      // 打开回溯
      const { from, to, diff } = timeInfo;
      const { systemId, systemType } = query
      const params = {
        systemId,
        type: systemType,
        from,
        to,
        pointCount: 30,
      };
      traceBackConfig.loading = true;
      traceBackGraph(params)
        .then((res) => {
          const data = res.data || [];
          data.sort(
            (a, b) =>
              dayjs(a.startTime).valueOf() - dayjs(b.startTime).valueOf()
          );
          const traceBackData = [];
          forEach(data, (item, idx) => {
            const {
              startTime,
              endTime,
              instances: apiNodes,
              edges: apiEdges,
            } = item;

            const { nodes, edges } = buildApiData(
              apiNodes,
              apiEdges,
              diff,
              attachDataType.value
            );
            traceBackData.push({
              startTime,
              endTime,
              time:
                idx === 0
                  ? dayjs(startTime).valueOf()
                  : dayjs(endTime).valueOf(),
              topoData: getTopoDataByIsMerge({ nodes, edges }),
              isError: some(nodes, (node) => getNodeAndEdgeStatus(node) === 1),
            });
          });

          trackBackData.value = traceBackData
        })
        .finally(() => {
          traceBackConfig.loading = false;
        });
    }
    traceBackConfig.isTraceBack = !traceBackConfig.isTraceBack
    // console.log(traceBackConfig.isTraceBack ,' isTraceBack');

  }
  // console.log(isFullScreen, 'isFull');

  return {
    mode,
    attachDataType,
    attachDataTypeText,
    syncEntranceConfig,
    traceBackConfig,
    isFullScreen,
    trackBackData,
    dataFilter,
    filters,
    nodeModes,
    nodeMode,
    tipVisible,
    updateAutoSync,
    changeAttachDataType,
    onMerge,
    onTriggerTrackBack,
    onSaveTopoChange,
  };
}
